import datetime
import wsgiref.handlers
import logging
log = logging.getLogger("dbmaint")

from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.api import memcache

import statsdb

class UpdateTag(webapp.RequestHandler):
  def get(self):
    if 0 == len(self.request.get("begin")):
      begin = datetime.datetime.strptime("197001010000", "%Y%m%d%H%M%S")
    else:
      begin = datetime.datetime.strptime(self.request.get("begin"), "%Y%m%d%H%M%S")
    if 0 == len(self.request.get("end")):
      end = datetime.datetime.strptime("207001010000", "%Y%m%d%H%M%S")
    else:
      end = datetime.datetime.strptime(self.request.get("end"), "%Y%m%d%H%M%S")
    self.response.headers["Content-Type"] = "text/plain"
    
    tags = {}
    tagIndexes = {}
    if len(self.request.get("pagesize")) > 0:
      pagesize = int(self.request.get("pagesize"))
    else:
      pagesize = 100
    bookmark = None
    while True:
      records, bookmark = statsdb.GetRecords("inputtime", begin, end, bookmark, pagesize)
      for record in records:
        for tagName in record.tags:
          if tags.has_key(statsdb.GenTagKeyName(tagName)):
            tag = tags[statsdb.GenTagKeyName(tagName)]
          else:
            tag = statsdb.GetTag(tagName)[1]
            if tag is None:
              tag = statsdb.Tag(key_name = statsdb.GenTagKeyName(tagName), name = tagName)
          statsdb.BuildTagIndex(tagName, tagIndexes)
          tag.count = len(tag.records)
          if record.key() not in tag.records:
            tag.records.append(record.key())
            tag.count += 1
            for otherTag in record.tags:
              if otherTag != tagName \
              and otherTag not in tag.related:
                tag.related.append(otherTag);
          tags[statsdb.GenTagKeyName(tagName)] = tag
      self.response.out.write(str(len(records)) + " records counted.\n")
      if bookmark is None: break
      
    if len(self.request.get("batch")) > 0:
      batch = int(self.request.get("batch"))
    else:
      batch = 50
    statsdb.DBBatch(db.put, tags.values(), batch)
    statsdb.UpdateEntity(tags, True)
    statsdb.DBBatch(db.put, tagIndexes.values(), batch)
    statsdb.UpdateEntity(tagIndexes, True)
    self.response.out.write(str(len(tags)) + " tags counted.\n")
    self.response.out.write(str(len(tagIndexes)) + " tag's indexes counted.\n")
      
class UpdateHistory(webapp.RequestHandler):
  def get(self):
    if 0 == len(self.request.get("begin")):
      begin = datetime.datetime.strptime("197001010000", "%Y%m%d%H%M%S")
    else:
      begin = datetime.datetime.strptime(self.request.get("begin"), "%Y%m%d%H%M%S")
    if 0 == len(self.request.get("end")):
      end = datetime.datetime.strptime("207001010000", "%Y%m%d%H%M%S")
    else:
      end = datetime.datetime.strptime(self.request.get("end"), "%Y%m%d%H%M%S")
    self.response.headers["Content-Type"] = "text/plain"
    
    if len(self.request.get("pagesize")) > 0:
      pagesize = int(self.request.get("pagesize"))
    else:
      pagesize = 100
    histories = {}
    bookmark = None
    while True:
      records, bookmark = statsdb.GetRecords("inputtime", begin, end, bookmark, pagesize)
      for record in records:
        if True == statsdb.GetHistory(record.tags)[0] \
        or True == histories.has_key(statsdb.GenHistoryKeyName(record.tags)):
          continue
        record.tags.sort()
        histories[statsdb.GenHistoryKeyName(record.tags)] = \
          statsdb.History(key_name=statsdb.GenHistoryKeyName(record.tags),
                          tags=" ".join(record.tags))      
      self.response.out.write(str(len(records)) + " records counted.\n")
      if bookmark is None: break

    if len(self.request.get("batch")) > 0:
      batch = int(self.request.get("batch"))
    else:
      batch = 50
    statsdb.DBBatch(db.put, histories.values(), batch)
    statsdb.UpdateEntity(histories, True)
    self.response.out.write(str(len(histories)) + " histories counted.\n")
    
class DeleteAll(webapp.RequestHandler):
  def get(self):
    self.response.headers["Content-Type"] = "text/plain"
    
    batch = 100
    if len(self.request.get("batch")) > 0:
      batch = int(self.request.get("batch"))
    entity = "all"
    if len(self.request.get("entity")) > 0:
      entity = self.request.get("entity")
    
    if "all" == entity \
    or "record" == entity:
      source = str(self.request.get("source"))
      while True:        
        if "all" == entity \
        or ("record" == entity \
            and "all" == source):
          records = statsdb.Record.all().fetch(batch)
        else:
          records = statsdb.Record.all().filter("source =", source).fetch(batch)
        if 0 == len(records): break
        self.response.out.write(str(statsdb.DeleteTagRecords(records)) + " tags deleted.\n")        
        statsdb.DBBatch(db.delete, records)
        self.response.out.write(str(len(records)) + " records deleted.\n")
        statsdb.UpdateEntity(dict((statsdb.GenRecordKeyName(k.date, k.tags), None) for k in records), False)
    
    if "all" == entity \
    or "tag" == entity:
      while True:
        tags = statsdb.Tag.all().fetch(batch)
        if 0 == len(tags): break
        db.delete(tags)
        self.response.out.write(str(len(tags)) + " tags deleted.\n")
        statsdb.UpdateEntity(dict((statsdb.GenTagKeyName(k.name), None) for k in tags), False)
      
    if "all" == entity \
    or "history" == entity:
      while True:
        histories = statsdb.History.all().fetch(batch)
        if 0 == len(histories): break
        db.delete(histories)
        self.response.out.write(str(len(histories)) + " records deleted.\n")
        statsdb.UpdateEntity(dict((statsdb.GenHistoryKeyName(k.tags.split(" ")), None) for k in histories), False)


class ViewRecord(webapp.RequestHandler):
  def get(self):
    if 0 == len(self.request.get("begin")):
      begin = datetime.datetime.strptime("197001010000", "%Y%m%d%H%M%S")
    else:
      begin = datetime.datetime.strptime(self.request.get("begin"), "%Y%m%d%H%M%S")
    if 0 == len(self.request.get("end")):
      end = datetime.datetime.strptime("207001010000", "%Y%m%d%H%M%S")
    else:
      end = datetime.datetime.strptime(self.request.get("end"), "%Y%m%d%H%M%S")
    if 0 == len(self.request.get("op")):
      op = "count"
    else:
      op = self.request.get("op")
    if len(self.request.get("pagesize")) > 0:
      pagesize = int(self.request.get("pagesize"))
    else:
      pagesize = 100
    bookmark = None
    count = 0
    while True:
      records, bookmark = statsdb.GetRecords("date", begin, end, bookmark, pagesize)
      count += len(records)
      if "print" == op:
        for r in records:
          print r.date.strftime(str(r.dfmt)), r.value, r.unit, " ".join(r.tags)
      if bookmark is None: break
    self.response.out.write(str(count) + " records counted\n")
    
class Memcache(webapp.RequestHandler):
  def get(self):
    self.response.headers["Content-Type"] = "text/plain"
    self.response.out.write("Current Memcache:\n")
    self.response.out.write("hits:"+str(memcache.get_stats()["hits"])+"\n")
    self.response.out.write("misses:"+str(memcache.get_stats()["misses"])+"\n")
    self.response.out.write("byte_hits:"+str(memcache.get_stats()["byte_hits"])+"\n")
    self.response.out.write("items:"+str(memcache.get_stats()["items"])+"\n")
    self.response.out.write("bytes:"+str(memcache.get_stats()["bytes"])+"\n")
    self.response.out.write("oldest_item_age:"+str(memcache.get_stats()["oldest_item_age"])+"\n")
    
    if "flushall" == self.request.get("op"):
      memcache.flush_all()
      self.response.out.write("After Flush:\n")
      self.response.out.write("hits:"+str(memcache.get_stats()["hits"])+"\n")
      self.response.out.write("misses:"+str(memcache.get_stats()["misses"])+"\n")
      self.response.out.write("byte_hits:"+str(memcache.get_stats()["byte_hits"])+"\n")
      self.response.out.write("items:"+str(memcache.get_stats()["items"])+"\n")
      self.response.out.write("bytes:"+str(memcache.get_stats()["bytes"])+"\n")
      self.response.out.write("oldest_item_age:"+str(memcache.get_stats()["oldest_item_age"])+"\n")




def main():
  application = webapp.WSGIApplication([("/dbupdatetag", UpdateTag), 
                                        ("/dbupdatehistory", UpdateHistory),
                                        ("/dbviewrecord", ViewRecord),
                                        ("/dbdeleteall", DeleteAll),
                                        ("/dbmemcache", Memcache)
                                        ],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == "__main__":
  main()
